
#include "nane/core/FileLogger.h"
#include "nane/core/crt/filesystem.h"
#include "nane/core/stackstring.h"
#include "nane/core/crt/Time.h"
#include "nane/core/IO.h"

namespace nane
{
    ////////////////////////////////////////////////////////////////////////////////////////////////
    FileLogger::FileLogger()
        : m_file( NullPtr )
    {
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    FileLogger::~FileLogger()
    {
        Close();
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    bool FileLogger::Open( const char* _filename, bool _dontOverwrite )
    {
        Close();
        m_file = FileSystem::OpenWriteFile(_filename);
        if( m_file != NullPtr && _dontOverwrite )
        {
            m_file->Seek(m_file->Size());
            IO<IOUnsafe>::Write(m_file.Get(), '\n');
        }
        return m_file != NullPtr;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void FileLogger::Close()
    {
        m_file = NullPtr;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    void FileLogger::Log( const char* _message, const char* _file, const char* _line
                        , const char* _function, ELogMessageLevel::raw_type _messageLevel )
    {
        if( m_file != NullPtr )
        {
            StackString<1024> buffer;
            if( _messageLevel < ELogMessageLevel::Info )
            {
                buffer.assign("[%1] %2: (%3:%4 '%5') %6\n")
                        << Time::GetLocalTime()
                        << ELogMessageLevel::toString(enum_cast<ELogMessageLevel>(_messageLevel))
                        << _file
                        << _line
                        << _function
                        << _message;
            }
            else
            {
                buffer.assign("[%1] %2: %3\n")
                        << Time::GetLocalTime()
                        << ELogMessageLevel::toString(enum_cast<ELogMessageLevel>(_messageLevel))
                        << _message;
            }
            m_file->Write(reinterpret_cast<const byte*>(buffer.begin()), buffer.size());
            if( _messageLevel == ELogMessageLevel::Error )
            {
                m_file->Flush();
            }
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
}   // namespace nane
